#include "utc_timer.h"

#define LeapYearSeconds           ((uint32_t)31622400)
#define NonleapYearSeconds        ((uint32_t)31536000)

static const uint8_t monthTable[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; 

// 1:是闰年 0：不是闰年
static uint8_t isLeapYear(uint16_t AYear)
{   
    //return (AYear % 4 == 0 && AYear % 100 != 0) || AYear % 400 == 0;
    return  !(AYear % (AYear % 100 ? 4 : 400));
}

// 获得周几
// 示例 2018年7月19日， 参数 2018/7/19
uint8_t RTC_GetWeekDay(uint16_t AYear, uint8_t AMonth, uint8_t ADay)
{
    uint8_t result = 0;

    if (AMonth == 1 || AMonth == 2)
    {
        AMonth += 12;
        AYear--;
    }

    result = (ADay + 2 * AMonth + 3 * (AMonth + 1) / 5 + AYear + AYear / 4 - AYear / 100 + AYear / 400) % 7;

    result++;

    if (result == 7)
        result = 0;

    return result;
} 

// 2000年开始的时间戳
uint32_t RTC_MakeUnixStamp(RTCStampType_t StampType, 
                            uint16_t AYear, uint8_t AMonth, uint8_t ADay,
                            uint8_t  AHour, uint8_t AMin,   uint8_t ASec)
{
    uint32_t result = 0;
    uint16_t Temp = 0;
    uint16_t startYear, endYear;

    switch (StampType){
    case StampType2000:
        startYear = 2000;
        endYear   = 2078;
        break;
    case StampType1970:
        startYear = 1970;
        endYear   = 2038;
        break;
    }

    if (AYear >= startYear && AYear <= endYear)
    {
        // 年计时
        for (Temp = startYear; Temp < AYear; Temp++)
        {
            if (isLeapYear(Temp))
                result += LeapYearSeconds;
            else
                result += NonleapYearSeconds;
        }

        // 月计时
        AMonth--;
        for (Temp = 0; Temp < AMonth; Temp++)
        {
            result += (uint32_t)monthTable[Temp] * 86400;
            // 闰年多一天
            if (isLeapYear(AYear) && (Temp == 1))
                result += 86400;
        }

        // 日计时
        result += (uint32_t)(ADay - 1) * 86400;

        // 时计时
        result += (uint32_t)AHour * 3600;
        result += (uint32_t)AMin * 60;
        result += ASec;
    }

    return result;
}

void RTC_MakeCalendar(RTCStampType_t StampType, uint32_t ATimeStamp, TIME_System_t* Calendar)
{
    uint32_t Temp;
    uint16_t TempCount;
    uint16_t startYear, endYear;

    switch (StampType){
    case StampType2000:
        startYear = 2000;
        endYear   = 2078;
        break;
    case StampType1970:
        startYear = 2000;
        endYear   = 2078;
        break;
    }    

    Temp = ATimeStamp / 86400;

    TempCount = startYear; // 标记起始年份
    while(Temp >= 365)
    {
        if (isLeapYear(TempCount))
        {
            if (Temp >= 366)
                Temp -= 366;
            else
            {
                TempCount++; break;
            }
        }
            
        else
            Temp -= 365;

        TempCount++;
    }

    Calendar->year = TempCount;

    TempCount = 0; // 标记起始月份
    while (Temp >= 28)
    {
        if (isLeapYear(Calendar->year) && (TempCount == 1))
        {
            if (Temp >= 29)
                Temp -= 29;
            else
                break;
        }
        else
        {
            if ( Temp >= monthTable[TempCount])
                Temp -= monthTable[TempCount];
            else
                break;
        }
        TempCount++;
    }

    Calendar->month = TempCount + 1;
    Calendar->day   = Temp + 1;

    Temp = ATimeStamp % 86400; // 得到秒数

    Calendar->hour = Temp / 3600;
    Temp %= 3600;

    Calendar->minute = Temp / 60;
    Calendar->second = Temp % 60;
    Calendar->dayOfWeek = RTC_GetWeekDay(Calendar->year, Calendar->month, Calendar->day);
    Calendar->milliseconds = 0;
}
